#![feature(nll)]
extern crate sdl2;
use sdl2::pixels::{Color};
use sdl2::event::{Event, WindowEvent};

pub mod geom;
pub mod frag;
pub mod diff;
pub mod tree;

type V = tree::Virtual<frag::Frag>;

fn scene_virtual(n: u32) -> V {
  use frag::{FragInfo};
  use geom::{Dim};
  use sdl2::pixels::{Color};
  use frag::FragSpine::*;
  use frag::AlignH::*;
  use frag::AlignV::*;

  let n1 = (n + 8) * 5;
  let n2 = (n + 10) * 5;
  let n3 = (n + 12) * 5;

  V::branch(Container, FragInfo {
    bounds: Dim(600, 400),
    align_h: Center,
    align_v: Middle,
  }, vec![
    frag::fill(Color::RGB(255, 255, 255)).into(),
    V::branch(PackLR, FragInfo::with_align(Left, Top), vec![
      frag::rect(Dim(n1, n1), Color::RGB(255, 0, 40)).into(),
      frag::rect(Dim(n2, n2), Color::RGB(0, 100, 200)).into(),
      frag::rect(Dim(n3, n3), Color::RGB(255, 230, 0)).into(),
    ]),
  ])
}

fn main() {
  let sdl = sdl2::init().unwrap();
  let mut events = sdl.event_pump().unwrap();

  let vid = sdl.video().unwrap();
  let mut canvas: sdl2::render::Canvas<_> =
    vid.window("R", 800, 600)
       .build()
       .unwrap()
       .into_canvas()
       .build()
       .unwrap();

  let mut tree = tree::Tree::default();
  let mut size = geom::Dim(800, 600);
  let mut need_update = true;
  let mut n = 0;

  'renderloop: loop {
    if need_update {
      use std::time::{Instant};
      let start = Instant::now();
      tree.impose(scene_virtual(n));
      tree.underlying.calculate_geometry(size);
      print!("{:?}\n", Instant::now() - start);
      need_update = false;
    }

    for evt in events.poll_iter() {
      match evt {
        Event::Quit { .. } =>
          break 'renderloop,

        Event::Window { win_event: WindowEvent::Resized(w, h), .. } => {
          size = geom::Dim(w as u32, h as u32);
          need_update = true;
        }

        Event::MouseButtonDown { .. } => {
          n += 1;
          need_update = true;
        }

        _ => (),
      }
    }

    {
      use frag::{DrawFrag};

      canvas.set_draw_color(Color::RGB(0, 0, 0));
      canvas.clear();
      canvas.draw_frag(&tree.underlying);
      canvas.present();
      std::thread::sleep(
        std::time::Duration::from_micros(1000000 / 64)
      );
    }
  }
}
